package com.example.demo.Service.lmp;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.Dto.PlaceOrderDto;
import com.example.demo.Dto.UpdateOrderDto;
import com.example.demo.Mapper.OrderMapper;
import com.example.demo.Service.AddressService;
import com.example.demo.Service.OrderItemService;
import com.example.demo.Service.OrderService;
import com.example.demo.Util.RedisUtli;
import com.example.demo.Util.ThreadLocallUtil;
import com.example.demo.Util.ThreadPoolUtil;
import com.example.demo.VO.AddressInfoVo;
import com.example.demo.VO.CartItem;
import com.example.demo.VO.OrderInfoVo;
import com.example.demo.po.Address;
import com.example.demo.po.Order;
import com.example.demo.po.OrderItem;
import org.joda.time.DateTime;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class OrderServicelmp extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Autowired
    private RedisUtli redisUtli;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private AddressService addressService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Override
    @Transactional
    // 创建订单
    public String addOrders(PlaceOrderDto placeOrderDto) {
        List<CartItem> cartItems = placeOrderDto.getCartItems();
        Order bean = BeanUtil.toBean(placeOrderDto, Order.class);
        bean.setUserId(ThreadLocallUtil.getUser().getUserId());
        bean.setId(redisUtli.generateId("订单"));
        bean.setStatus(0);
        bean.setCreateTime(DateTime.now());
        bean.setUpdateTime(DateTime.now());
        bean.setDeleted(0);
        if (!(save(bean))){
            throw new RuntimeException("订单:添加失败");
        }
        List<OrderItem> orderItems = new ArrayList<>();
        for (CartItem cartItem : cartItems) {
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderId(bean.getId().toString());
            orderItem.setCartItemId(cartItem.getCartItemId());
            orderItem.setProductId(cartItem.getProductId());
            orderItem.setQuantity(cartItem.getQuantity());
            orderItem.setStatus(0);
            orderItem.setCreateTime(DateTime.now());
            orderItem.setUpdateTime(DateTime.now());
            orderItems.add(orderItem);
        }
        if (!(orderItemService.saveBatch(orderItems))){
            throw new RuntimeException("订单:添加失败");
        }
        redisTemplate.opsForValue().getAndDelete("订单"+bean.getId());
        //TODO,在查询订单功能完成后调用，实现订单支付超时关闭功能
        rabbitTemplate.convertAndSend("order-exchange", "delay", bean.getId(), new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                // 使用 x-delay 头设置延迟时间为 5000000毫秒,
                message.getMessageProperties().getHeaders().put("x-delay", 5000000);
                return message;
            }});
        return bean.getId().toString();
    }

    @Override
    @Transactional
    // 修改订单信息
    public void updateOrder(UpdateOrderDto updateOrderDto) {
        update(new UpdateWrapper<Order>().eq("id", updateOrderDto.getOrderId())
                .set("status", updateOrderDto.getStatus())
                .set("update_time", DateTime.now())
                .set(updateOrderDto.getUserCurrency() != null,"user_currency", updateOrderDto.getUserCurrency())
                .set(updateOrderDto.getAddressId() != null,"address_id", updateOrderDto.getAddressId()));
        redisTemplate.opsForValue().getAndDelete("订单"+updateOrderDto.getOrderId());
    }

    @Override
    // 订单ID查询订单信息
    public OrderInfoVo getOrderById(String orderId) {
        Object o = redisTemplate.opsForValue().get("订单" + orderId);
        if (o != null){
            return (OrderInfoVo) o;
        } else if (o==" ") {
            throw new RuntimeException("订单:查询失败,没有该订单");
        }
        Order byId = getById(orderId);
        if (byId == null){
            redisTemplate.opsForValue().set("订单" + orderId, " ");
            throw new RuntimeException("订单:查询失败,没有该订单");
        }
        OrderInfoVo orderInfoVo = BeanUtil.copyProperties(byId, OrderInfoVo.class);
        orderInfoVo.setAddress(BeanUtil.copyProperties(addressService.getById(byId.getAddressId()), AddressInfoVo.class));
        List<CartItem> orderId1 = orderItemService.list(new QueryWrapper<OrderItem>().eq("order_id", orderId)).stream().
                map(orderItem -> BeanUtil.copyProperties(orderItem, CartItem.class)).
                collect(Collectors.toList());
        orderInfoVo.setCartItems(orderId1);
        return orderInfoVo;
    }
}
